from Config import *
from Pinger import *
from Logger import *
from Listener import *
#from MessageHandler import *

from socket import *
from threading import *
from collections import deque

class MessageSender(threading.Thread):
    def __init__(self, logger, sock, server):
        threading.Thread.__init__(self)
        self.logger = logger
        self.sock = sock
        self.server = server
        self.queue = deque()
#------------------------------------------------------------------------------------------------------ 
    # TODO: data kan leeg zijn. dus data = None ???
    def add_queue(data, address):
        queue.append((data, address))

    def run():
        while True:
            try:
                data, address = queue.popleft()
                sock.sendto(data, address)
            except IndexError:
                pass
                    
#------------------------------------------------------------------------------------------------------            

    # send list of our clients
    def msg110(self, msgno, length, naam):
        # send to other clients in network
        for client in self.server.clients:
            new_message = ("Sending a 110 to: "+client.address+"message no: "+msgno)
            logger.add_queue(new_message, "MessageSender")
            
            msg = msgno+" "+length+" "+client.name
            new_message = MessageHandler.create_message(110, 0, msg)
            add_queue(new_message, client.address)
            
        # send to our children
        for child in self.server.children:
            for client in server.clients:
                new_message = ("Sending a 110 to: "+client.address+"message no: "+msgno)
                logger.add_queue(new_message, "MessageSender")
                
                msg = msgno+" "+length+" "+client.name
                new_message = MessageHandler.create_message(110, 0, msg)
                add_queue(new_message, child.address)
        
        # send to our parent
        for client in self.server.clients:
            new_message = ("Sending a 110 to: "+client.address+"message no: "+msgno)
            logger.add_queue(new_message, "MessageSender")
            
            msg = msgno+" "+length+" "+client.name
            new_message = MessageHandler.create_message(110, 0, msg)
            add_queue(new_message, self.server.parent)
#------------------------------------------------------------------------------------------------------         
    # connection with client is already broken
    # notificate servers, clients and control server
    # generated by msg120
    # hier hetzelfde als bij 110 deze methode moet gewoon gebruikt kunnen worden voor een ontvangende methode.
    # TODO: HIER WIL JE EERST TESTEN WELKE SERVER/CLIENT 32 SECONDEN LANG NIET REAGEREN
    def msg130(name, greet = None):

        # TODO: ZOEK WEGGEVALLEN CLIENT/SERVER
        
        # notificate rest of clients
        for client in self.server.clients:
            if (greet): 
                msg = name+ " "+greet
                msg = MessageHandler.create_message(130, 1, msg)
            else:
                msg = MessageHandler.create_message(130, 1, (name))
                add_queue(msg, client.address)
            
            msg = "Sending a 130 to: "+client.name+" with name: "+name+\
            " and message: "+greet
            logger.add_queue(msg, "MessageSender")
        
        # notificate serversmsg60
        for child in self.server.children:
            if (greet):                
                msg = MessageHandler.create_message(130, 1, (name, greet))
            else:
                msg = MessageHandler.create_message(130, 1, (name))
                add_queue(msg, child.address)
            
            msg = "Sending a 130 to: "+child.tag+" with name: "+name+\
            " and message: "+greet
            logger.add_queue(msg, "MessageSender")
        
#------------------------------------------------------------------------------------------------------         
    # send pong
    def msg150(identification, address):
        msg =   "Sending a 150 to: %s with identification: %s" % (address, identification)
        logger.add_queue(msg, "MessageSender")
        
        msg = MessageHandler.create_message(150, 0, identification)
        mSender.add_queue(msg, address)
        
#------------------------------------------------------------------------------------------------------ 
    # notificate servers and clients change name succeeded
    def msg170(oldname, newname):
        for server in self.server.children:
            msg = "Sending a 170 to: " + server.address+ \
                " with old name: " + str(oldname)+" and new name: " + str(newname)
            logger.add_queue(msg, "MessageSender")
            msg = oldname + " " + newname
            msg = MessageHandler.create_message(170, 1, msg)
            add_queue(msg, server.address)
        
        for client in self.server.clients:
            msg = "Sending a 170 to: " + client.address+ \
                " with old name: " + str(oldname)+" and new name: " + str(newname)
            logger.add_queue(msg, "MessageSender")
            msg = oldname + " " + newname
            msg = MessageHandler.create_message(170, 1, msg)
            add_queue(msg, client.address)
#------------------------------------------------------------------------------------------------------ 

        # server sends this text/action message to other servers and clients
        def msg300_310(source, destination, text, type):
            if destination == "#all":                
                for client in self.server.clients:
                    msg = "Sending a "+ type + " from: "+ source +" to: " + client.address
                    logger.add_queue(msg, "MessageSender")
                    new_message = MessageHandler.create_message(type, 1, source+" "+destination+" "+text)
                    add_queue(new_message , client.address)
                for server in server.children():
                    msg = "Sending a "+ type + " from: "+ source +" to: " + server.address
                    logger.add_queue(msg, "MessageSender")
                    new_message = MessageHandler.create_message(type, 1, source+" "+destination+" "+text)
                    add_queue(new_message , server.address)
            else:
                for client in server.clients():
                    if destination == client.name:
                        msg = "Sending a "+ type + " from: "+ source +" to: " + destination
                        logger.add_queue(msg, "MessageSender")
                        new_message = MessageHandler.create_message(type, 1, source+" "+destination+" "+text)
                        add_queue(new_message , client.addresss)
#-------------------------------------------------------------------------------------------------------            
    # registration succeeded, notificate client (server to client message)
    def msg500(address):
        for client in self.server.clients():
            if(address == client.address):
                msg = "Sending a 500 to: " + client.name
                logger.add_queue(msg, "MessageSender")
                msg = MessageHandler.create_message(500, 1, "")
                add_queue(msg, address)
                break
#------------------------------------------------------------------------------------------------------

        def msg601(tag):
            new_message = "Sending 601 to Control server"
            logger.add_queue(new_message , "Messagesender")
            new_message = MessageHandler.create_message(601, 1, tag)
            add_queue(new_message, CONTROL_SERVER_ADDRESS)
#-------------------------------------------------------------------------------------------------------          

    # send 700 if this server wants to disconnect
    def msg700(address):
        msg = "Server "+address+" is leaving. "
        for server in self.server.children:
            if server.address == address:
                if server.clients.name in ADMINS:
                    logger.add_queue(msg, "MessageSender")
                    add_queue(MessageHandler.create_message(700, 1, msg))
                